from datetime import datetime,timedelta
import sqlalchemy
import jwt
from flask import Blueprint, jsonify, request, session, current_app
from flask_jwt_extended import create_access_token, jwt_required, get_jwt_identity
from jwt import PyJWTError
from sqlalchemy import func, cast

from exts import mail, db
from server.resource.util.const import generate_tokens,verify_tokens
from server.resource.util.MD5 import md5_encrypt,md5_verify
from models import EmailCaptchaaModel, UserModel, IncomeModel, Access_Token
from server.resource.util.ApiResponse import ApiResponse
from flask_mail import Message
import string
import random

bp = Blueprint("user",__name__,url_prefix="/user")

@bp.route("/login",methods=['post'])
def login():
    data = request.get_json()
    username = data['username']
    password = data['password']
    user = UserModel.query.filter_by(username=username).first()
    if not user:
        user = UserModel.query.filter_by(email=username).first()
        if not user:
            return jsonify(ApiResponse.server_error("没有该用户,请前往注册"))
    if md5_verify(password,user.password):
        # print(user.state)
        user.join_time = datetime.now()
        db.session.commit()

        # session['is_login'] = 'true'
        # session['email'] = user.email
        # session['username'] = user.username
        # session['state'] = user.state

        MyUser = {
            'id': user.id,
            'username': user.username,
            'state': user.state
        }

        access_token = create_access_token(identity=user.id,
                                           additional_claims=MyUser)
        token = Access_Token(access_token=access_token,user_id=user.id)
        db.session.add(token)
        db.session.commit()

        ans = {}
        ans['access_token'] = access_token
        return jsonify(ApiResponse.success(ans))
        #1普通用户2会员用户0admin
        #1月费2季费3年费
    else:
        return jsonify(ApiResponse.server_error("密码错误"))


@bp.route("/logout", methods=['GET'])
@jwt_required()
def logout():
    # 获取当前用户的访问令牌
    user_id = get_jwt_identity()
    # user_id = 6
    token = Access_Token.query.filter_by(user_id=user_id).first()
    token.is_delete = 1
    db.session.commit()
    # 返回成功登出的消息
    return jsonify(ApiResponse.success())


@bp.route('/protected', methods=['GET'])
@jwt_required()
def protected():
    # 获取当前用户的 ID，这是通过 identity 参数设置的
    user_id = get_jwt_identity()
    token = Access_Token.query.filter_by(user_id=user_id,is_delete=0).first()
    if not token:
        return jsonify(ApiResponse.server_error("当前用户不是登录状态"))
    # 获取 JWT token 的其他声明
    claims = request.jwt_claims

    # 从声明中获取自定义的声明
    username = claims.get('username', None)
    state = claims.get('state', None)

    # 这里访问受保护的资源，并使用获取到的信息
    return f"Welcome, {username}! Your user ID is {user_id} and your state is {state}."

@bp.route("/register",methods=['POST'])
def register():
    data = request.get_json()
    username = data['username']
    password = data['password']
    email = data['email']
    captcha = data['captcha']
    user = UserModel.query.filter_by(email=email,username=username).first()
    # print(type(user))
    if not user:
        email_captcha = EmailCaptchaaModel.query.filter_by(email=email,is_delete=False).first()
        if datetime.now() - email_captcha.join_time > timedelta(minutes=2):
            email_captcha.is_delete = True
            db.session.commit()
            return jsonify(ApiResponse.server_error("验证码已超时间"))
        if captcha == email_captcha.captcha:
            password = md5_encrypt(password)
            user = UserModel(username=username,password=password,email=email)
            email_captcha.is_delete = True
            db.session.add(user)
            db.session.commit()
            return jsonify(ApiResponse.success())
        else:
            return jsonify(ApiResponse.server_error("验证码错误~"))
    else:
        return jsonify(ApiResponse.server_error("该email已经注册过咯，请重新注册~"))
    return jsonify(ApiResponse.success())
#注册验证码
@bp.route("/captcha/email",methods=['POST'])
def get_email_captcha():
    data = request.get_json()
    email = data['email']
    if not email:
        return jsonify(ApiResponse.server_error("你没有填写邮箱"))
    source = string.digits*4
    captcha = random.sample(source,6)
    captcha = "".join(captcha)
    message = Message(subject="TruePhoto验证码",recipients=[email],body=f"感谢使用TruePhoto,您的验证码是：{captcha}")
    mail.send(message)
    # print(captcha)
    email_captcha = EmailCaptchaaModel(email=email,captcha=captcha)
    db.session.add(email_captcha)
    db.session.commit()

    return jsonify(ApiResponse.success())

# 重置密码的验证码
@bp.route("/resetCaptcha",methods=['POST'])
def get_reset_captcha():
    data = request.get_json()
    email = data['email']
    if not email:
        return jsonify(ApiResponse.server_error("你没有填写邮箱"))
    user = UserModel.query.filter_by(email=email).first()
    if not user:
        return jsonify(ApiResponse.server_error("没有该用户，请前往注册"))
    source = string.digits*4
    captcha = random.sample(source,6)
    captcha = "".join(captcha)
    message = Message(subject="TruePhoto验证码",recipients=[email],body=f'感谢使用TruePhoto,您的验证码是：{captcha}')
    mail.send(message)
    email_captcha=EmailCaptchaaModel(email=email,captcha=captcha)
    db.session.add(email_captcha)
    db.session.commit()
    return jsonify(ApiResponse.success())
#重置密码
@bp.route("/resetPassword",methods=['POST'])
def reset_password():
    data = request.get_json()
    email = data['email']
    password = data['password']
    captcha = data['captcha']

    email_captcha = EmailCaptchaaModel.query.filter_by(email=email,is_delete=False).first()
    if datetime.now() - email_captcha.join_time > timedelta(minutes=10):
        email_captcha.is_delete = True
        db.session.commit()
        return jsonify(ApiResponse.server_error("验证码已超时间"))
    if email_captcha.captcha != captcha:
        return jsonify(ApiResponse.server_error("验证码错误"))
    user = UserModel.query.filter_by(email=email).first()
    user.password = md5_encrypt(password)
    email_captcha.is_delete = True
    db.session.commit()
    return jsonify(ApiResponse.success())

#获取普通用户和会员用户的个数
@bp.route("/getPeopleNumber",methods=['GET'])
def get_people_number():
    users_count = UserModel.query.filter_by(state='1', is_delete=False).count()
    member_users_count = UserModel.query.filter_by(state='2', is_delete=False).count()
    ans = {'users': users_count, 'member_users': member_users_count}
    print(ans)
    return jsonify(ApiResponse.success(ans))

@bp.route("/joinMember",methods=['POST'])
def join_member():
    data = request.get_json()
    username = data['username']
    member_state = data['member_state']
    if not member_state:
        return jsonify(ApiResponse.server_error())
    user = UserModel.query.filter_by(username=username).first()
    user.state = '2'
    user.member_state = member_state
    user.join_member_time = datetime.now()

    if member_state == '1':
        money = 29
    elif member_state == '2':
        money = 59
    elif member_state == '3':
        money = 199
    income = IncomeModel(amount=money)
    db.session.add(income)
    db.session.commit()

    return jsonify(ApiResponse.success())

@bp.route("/getAllMoney",methods=['GET'])
def get_all_money():
    # 获取全部收入
    total_income_query = db.session.query(func.sum(IncomeModel.amount)).filter_by(is_delete=False)
    total_income = total_income_query.scalar()

    # 获取过去一周的收入
    from_date = datetime.now() - timedelta(days=7)
    weekly_income_query = db.session.query(func.sum(IncomeModel.amount)).filter(
        IncomeModel.join_time > from_date,
        IncomeModel.is_delete == False
    )
    weekly_income = weekly_income_query.scalar()

    ans = {
        'total_income': total_income,
        'weekly_income': weekly_income
    }
    print(ans)
    return jsonify(ApiResponse.success(ans))


@bp.route("/getSevenDayMoney",methods=['GET'])
def get_seven_day_money():
    # 获取当前时间
    current_time = datetime.utcnow()
    # 计算一周前的时间
    one_week_ago = current_time - timedelta(days=7)

    # 查询过去一周每天的收入
    weekly_income_query = db.session.query(
        func.date(IncomeModel.join_time).label('date'),  # 使用 func.date 来获取日期部分
        func.sum(IncomeModel.amount).label('daily_income')
    ).filter(
        IncomeModel.join_time > one_week_ago,
        IncomeModel.join_time < current_time
    ).group_by(
        func.date(IncomeModel.join_time)  # 使用 func.date 来分组
    ).order_by(
        'date'
    )

    # 执行查询并获取结果
    weekly_income_data = weekly_income_query.all()

    ans = {}
    # 打印每天的收入
    for day_data in weekly_income_data:
        ans[f'{day_data.date}'] = day_data.daily_income
        print(f'{day_data.date}+{day_data.daily_income}')
    print(ans)

    return jsonify(ApiResponse.success(ans))

@bp.route('/getSevenDayUser',methods=['GET'])
def get_seven_day_user():
    # 获取当前时间
    current_time = datetime.utcnow()
    # 计算一周前的时间
    one_week_ago = current_time - timedelta(days=7)

    # 查询过去一周每天的新用户数和会员数的记录数
    weekly_user_count_query = db.session.query(
        func.date(UserModel.join_time).label('date'),  # 使用 func.date 来获取日期部分
        func.count(UserModel.id).label('daily_user_count')  # 统计每天的用户记录数
    ).filter(
        UserModel.state == '2',
        UserModel.join_time > one_week_ago,
        UserModel.join_time < current_time
    ).group_by(
        func.date(UserModel.join_time)  # 使用 func.date 来分组
    ).order_by(
        'date'
    )

    # 执行查询并获取结果
    weekly_user_count_data = weekly_user_count_query.all()

    ans = {}
    # 遍历查询结果，构建每天的用户数字典
    for day_data in weekly_user_count_data:
        ans[f'{day_data.date}'] = day_data.daily_user_count

    # 返回结果，使用 ApiResponse 包装结果
    return jsonify(ApiResponse.success(ans))

@bp.route('/getSevenDayVip',methods=['GET'])
def get_seven_day_vip():
    # 获取当前时间
    current_time = datetime.utcnow()
    # 计算一周前的时间
    one_week_ago = current_time - timedelta(days=7)

    # 查询过去一周每天的会员数的记录数
    weekly_vip_count_query = db.session.query(
        func.date(UserModel.join_member_time).label('date'),  # 使用 func.date 来获取日期部分
        func.count(UserModel.id).label('daily_vip_count')  # 统计每天的会员记录数
    ).filter(
        UserModel.state == '1' ,
        UserModel.join_member_time >= one_week_ago,
        UserModel.join_member_time < current_time
    ).group_by(
        func.date(UserModel.join_member_time)  # 使用 func.date 来分组
    ).order_by(
        'date'
    )

    # 执行查询并获取结果
    weekly_vip_count_data = weekly_vip_count_query.all()

    ans = {}
    # 遍历查询结果，构建每天的会员数字典
    for day_data in weekly_vip_count_data:
        ans[f'{day_data.date}'] = day_data.daily_vip_count

    # 返回结果，使用 ApiResponse 包装结果
    return jsonify(ApiResponse.success(ans))